home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mission 3
/
Mission 3.zip
/
Mission 3.iso
/
texte
/
qed
/
src
/
file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-11-09
|
15KB
|
752 lines
#include <errno.h>
#include <stat.h>
#include <time.h>
#include <unistd.h>
#include "global.h"
#include "aktion.h"
#include "comm.h"
#include "edit.h"
#include "find.h"
#include "icon.h"
#include "memory.h"
#include "olga.h"
#include "options.h"
#include "projekt.h"
#include "rsc.h"
#include "text.h"
#include "window.h"
#include "file.h"
static PATH last_path; /* letzter Pfad der Dateiauswahl */
/* Puffer-Länge zum Lesen/Schreiben */
#define BUFFERSIZE 4*1024L
void open_error(char *filename, int error)
{
FILENAME datei;
PATH path;
split_filename(filename, path, datei);
if (error == -33 && path_exists(path)) /* file not found und Pfad existiert */
snote(1, 0, NOTEXIST, datei);
else
snote(1, 0, READERR, datei);
}
int load(TEXTP t_ptr, bool verbose)
{
int antw;
bool null_byte;
antw = load_datei(t_ptr->filename, &t_ptr->text, verbose, &null_byte);
t_ptr->cursor_line = t_ptr->text.head.nachf;
t_ptr->readonly = file_readonly(t_ptr->filename);
if (null_byte)
t_ptr->moved++;
if (antw == 0)
{
t_ptr->file_date_time = file_time(t_ptr->filename,NULL,NULL);
}
else
t_ptr->file_date_time = -1L;
return(antw);
}
int load_datei(char *name, RINGP t, bool verbose, bool *null_byte)
{
int fd, antw;
long filesize;
bool nb = FALSE,
ol = FALSE;
/* größe der Datei ermitteln */
filesize = file_size(name);
if (filesize >= 0L)
{
fd = (int) Fopen(name, 0);
if (fd > 0)
{
char *buffer, *zeile;
ZEILEP start, next;
long l, p, bytes;
int n;
bool new_line, cr = FALSE, mem = TRUE;
/* Puffer anfordern */
buffer = (char *)malloc(BUFFERSIZE);
zeile = malloc(MAX_LINE_LEN + 2); /* + 2 für Zeilenende */
if (buffer == NULL || zeile == NULL)
{
note(1, 0, NOMEMORY);
return -39;
}
nb = FALSE;
graf_mouse(HOURGLASS, NULL);
/* Progress-Bar */
verbose = verbose && ((filesize >> 10) >= transfer_size);
if (verbose)
{
char str[40];
FILENAME file;
strcpy(str, rsc_string(LOADSTR));
file_name(name, file, FALSE);
strcat(str, file);
start_aktion(str, FALSE, filesize);
bytes = 0L;
}
/* Liste vorbereiten */
start = t->tail.vorg;
/* Einlesen */
l = Fread(fd, BUFFERSIZE, buffer);
n = 0;
new_line = FALSE;
while (mem && (l > 0))
{
p = 0;
while (mem && (p < l))
{
if (t->ending != binmode)
{
if (buffer[p] == 0x0D) /* CR -> Mac */
{
new_line = TRUE;
p++;
cr = TRUE;
t->ending = apple;
}
else if (buffer[p] == 0x0A) /* LF */
{
p++;
if (cr) /* CRLF -> TOS*/
{
cr = FALSE;
t->ending = tos;
}
else
{
new_line = TRUE; /* -> Unix */
t->ending = unix;
}
}
else if (n >= t->max_line_len) /* Überlänge */
{
ol = TRUE;
new_line = TRUE;
}
else
{
/* Nullbyte? */
if (buffer[p] == '\0')
{
nb = TRUE;
buffer[p] = ' '; /* Durch Leerzeichen ersetzen */
}
zeile[n] = buffer[p];
n++;
p++;
}
}
else /* binmode */
{
if (n >= (t->max_line_len - 1))
new_line = TRUE;
zeile[n] = buffer[p];
n++;
p++;
}
if (new_line)
{
zeile[n] = EOS;
start->nachf = new_col(zeile, n);
if (start->nachf == NULL)
mem = FALSE;
else
{
start = start->nachf;
if (ol)
{
start->info |= OVERLEN;
ol = FALSE;
}
}
n = 0;
new_line = FALSE;
}
} /* while */
if (verbose)
{
bytes += BUFFERSIZE;
do_aktion("", bytes);
}
l = Fread(fd, BUFFERSIZE, buffer);
/* EOF */
if (l == 0)
{
/* letzte Zeile ohne Zeilenende! */
if (n > 0)
{
zeile[n] = EOS;
start->nachf = new_col(zeile, n);
if (start->nachf == NULL)
mem = FALSE;
else
start = start->nachf;
}
/* letzte Zeile hatte ZE -> ein Dummyzeile anhängen */
else if (n == 0)
{
start->nachf = new_col(zeile, 0);
if (start->nachf == NULL)
mem = FALSE;
else
start = start->nachf;
}
}
} /* while */
if (mem)
{
/* Ring schließen */
t->tail.vorg = start;
start->nachf = &t->tail;
/* Anzahl der Zeilen ermitteln */
start = t->head.nachf;
next = start->nachf;
for (l = 0; !IS_TAIL(start); l++)
{
next->vorg = start;
start = next;
NEXT(next);
}
t->lines = l;
if (l > 1L)
col_delete(t, t->head.nachf);
antw = 0;
}
else
{
/* Speichermangel! Bisher gelesene Zeilen freigeben. */
next = FIRST(t);
while (next)
{
start = next;
NEXT(next);
free_col(start);
}
graf_mouse(ARROW, NULL);
note(1, 0, NOMEMORY);
antw = -39;
}
Fclose(fd);
free(buffer);
free(zeile);
if (verbose)
end_aktion();
graf_mouse(ARROW, NULL);
}
else
antw = fd;
}
else
antw = -1;
if (null_byte != NULL)
*null_byte = nb;
return(antw);
}
/*
* Ermittelt die anzahl der Bytes und Zeilen der übergebenen Datei.
* Wird bei der Projektverwaltung (Info) benutzt.
*/
int infoload(char *name, long *bytes, long *lines)
{
RING t;
int antw = 1;
if (file_exists(name))
{
init_textring(&t);
if (load_datei(name, &t, FALSE, NULL) == 0)
{
*bytes = textring_bytes(&t);
*lines = t.lines;
antw = 0;
}
kill_textring(&t);
}
else
{
char s[28];
*bytes = 0;
*lines = 0;
make_shortpath(name, s, 28);
snote(1, 0, READERR, s);
}
return antw;
}
/****************************************************************************/
long void backup_name(char *name, char *ext)
{
PATH new;
FILENAME new_name;
strcpy(new, name);
strcat(new, ".");
strcat(new, ext);
file_name(new, new_name, FALSE);
if (fs_long_name(new) >= strlen(new_name))
strcpy(name, new);
else
set_extension(name, ext);
}
static void restore_back_up(TEXTP t_ptr)
{
if (t_ptr->loc_opt->backup)
{
PATH old;
if (file_exists(t_ptr->filename))
Fdelete(t_ptr->filename);
strcpy(old, t_ptr->filename);
backup_name(old, t_ptr->loc_opt->backup_ext);
Frename(0, old, t_ptr->filename);
}
}
static void back_up(TEXTP t_ptr)
{
PATH new;
if (t_ptr->loc_opt->backup)
{
graf_mouse(HOURGLASS, NULL);
strcpy(new, t_ptr->filename);
backup_name(new, t_ptr->loc_opt->backup_ext);
if (file_exists(new)) /* Alte DUP-Datei löschen */
Fdelete(new);
Frename(0, t_ptr->filename, new);
graf_mouse(ARROW, NULL);
}
}
int save_datei(char *name, RINGP t, bool verbose)
{
int fd, antw;
fd = (int) Fcreate(name, 0);
if (fd > 0)
{
char end_str[3], *zeile, *buffer, *ptr;
int e_len, z_len;
long ret, count, b, rest, text_size;
ZEILEP lauf;
/* Puffer anfordern */
buffer = (char *)malloc(BUFFERSIZE);
zeile = (char *)malloc(MAX_LINE_LEN + 2);
if (buffer == NULL || zeile == NULL)
{
note(1, 0, NOMEMORY);
return -39;
}
graf_mouse(HOURGLASS, NULL);
/* Progress-Bar */
text_size = textring_bytes(t);
verbose = verbose && ((text_size >> 10) >= transfer_size);
if (verbose)
{
char str[40];
FILENAME file;
strcpy(str, rsc_string(SAVESTR));
file_name(name, file, FALSE);
strcat(str,file);
start_aktion(str, FALSE, text_size);
count = 0L;
}
/* String mit Zeilenende erzeugen */
switch (t->ending)
{
case tos :
strcpy(end_str, "\r\n");
e_len = 2;
break;
case unix :
strcpy(end_str, "\n");
e_len = 1;
break;
case apple :
strcpy(end_str, "\r");
e_len = 1;
break;
default:
strcpy(end_str, "");
e_len = 0;
break;
}
lauf = FIRST(t);
if (lauf != NULL)
{
b = 0L;
ret = 1;
ptr = buffer;
rest = BUFFERSIZE;
while ((!IS_TAIL(lauf)) && (ret > 0))
{
/* Zeile aus Text und Zeilenende zusammen setzen */
memcpy(zeile, TEXT(lauf), lauf->len);
z_len = lauf->len;
/*
* Das Zeilenende wird nur dann angehängt, wenn lauf nicht letzte
* Zeile ist. Gab es beim Laden der Datei in der letzten Zeile
* ein ZE, gibt es die Dummyzeile. Gab es das ZE nicht, wird auch
* kein ZE angehängt!
*/
if (!IS_LAST(lauf) && (e_len > 0) && !IS_OVERLEN(lauf))
{
memcpy(zeile + lauf->len, end_str, e_len);
z_len += e_len;
}
/* Passt die Zeile noch in den Puffer? */
if (z_len < rest)
{
/* komplett in den Puffer */
memcpy(ptr, zeile, z_len);
ptr += z_len;
b += z_len;
rest -= z_len;
}
else
{
/* nur soviel kopieren, wie noch passt */
memcpy(ptr, zeile, rest);
ptr += rest;
/* wegschreiben */
ret = Fwrite(fd, BUFFERSIZE, buffer);
if (verbose)
{
count += BUFFERSIZE;
do_aktion("", count);
}
if (ret != BUFFERSIZE)
ret = -ENOSPC;
/* und den Rest in den Puffer */
b = z_len - rest;
ptr = buffer;
memcpy(ptr, zeile + rest, b);
ptr += b;
rest = BUFFERSIZE - b;
}
NEXT(lauf);
}
/* Befindet sich noch etwas im Puffer und ist kein Fehler aufgetreten? */
if ((b > 0L) && (ret > 0))
{
ret = Fwrite(fd, b, buffer);
if (verbose)
{
count += b;
do_aktion("", count);
}
if (ret != b)
ret = -ENOSPC;
}
if (ret < 0)
antw = (int)ret;
else
antw = 0;
}
else
antw = 1;
Fclose(fd);
if (antw == -ENOSPC)
Fdelete(name);
free(buffer);
free(zeile);
if (verbose)
end_aktion();
}
else
antw = fd;
graf_mouse(ARROW, NULL);
return antw;
}
int save(TEXTP t_ptr)
{
int antw;
struct stat st;
if (file_exists(t_ptr->filename))
{
if (file_readonly(t_ptr->filename))
{
FILENAME file;
t_ptr->readonly = TRUE;
file_name(t_ptr->filename, file, FALSE);
snote(1, 0, READONLY, file);
return -39;
}
else
t_ptr->readonly = FALSE;
if (t_ptr->file_date_time != -1L)
{
long date_time = file_time(t_ptr->filename, NULL, NULL);
if (date_time != t_ptr->file_date_time)
{
FILENAME name;
file_name(t_ptr->filename, name, FALSE);
if (snote(1, 2, MOVED2, name) == 2)
return -1;
}
}
}
stat(t_ptr->filename, &st);
back_up(t_ptr);
antw = save_datei(t_ptr->filename, &t_ptr->text, TRUE);
if (antw == 0)
{
t_ptr->moved = 0;
t_ptr->file_date_time = file_time(t_ptr->filename, NULL, NULL);
t_ptr->asave = time(NULL);
/* OLGA informieren */
do_olga(OLGA_UPDATE, t_ptr->filename, NULL);
/* Attribute wieder herstellen */
chmod(t_ptr->filename, (st.st_mode & 0x0000FFFF));
if (getuid() == 0) /* nur root darf Owner ändern */
chown(t_ptr->filename, st.st_uid, st.st_gid);
}
else
{
if (antw == -ENOSPC)
{
char tmp[20];
make_shortpath(t_ptr->filename, tmp, 19);
snote(1, 0, NOSPACE, tmp);
}
else
note(1, 0, WRITEERR);
/* restore_back_up(t_ptr); */
t_ptr->file_date_time = -1L;
}
return antw;
}
int save_as(TEXTP t_ptr, char *name)
{
int antw;
if (file_exists(name))
{
if (file_readonly(name))
{
FILENAME file;
file_name(t_ptr->filename, file, FALSE);
snote(1, 0, READONLY, file);
return -39;
}
}
antw = save_datei(name, &t_ptr->text, TRUE);
if (antw != 0)
{
if (antw == -ENOSPC)
{
char tmp[20];
make_shortpath(t_ptr->filename, tmp, 19);
snote(1, 0, NOSPACE, tmp);
}
else
note(1, 0, WRITEERR);
/* restore_back_up(t_ptr);*/
}
return(antw);
}
bool save_new(char *name, char *mask, char *title)
{
PATH new;
bool ok = FALSE;
if ((name[0] == EOS) || (strcmp(name, rsc_string(NAMENLOS)) == 0))
strcpy(new, last_path);
else
strcpy(new, name);
if (select_single(new, mask, title))
{
if (strcmp(name, new) != 0) /* wirklich neuer Name? */
{
if (file_exists(new) && (note(1, 2, EXIST) == 2))
ok = FALSE;
else
{
strcpy(name, new);
ok = TRUE;
}
}
else
ok = FALSE;
}
return ok;
}
/*****************************************************************************/
/* Dateiauswahl */
/*****************************************************************************/
static bool multi_bin = FALSE;
void store_path(char *path)
{
PATH p;
split_filename(path, p, NULL);
if (strcmp(last_path, p) != 0) /* neuer Pfad? */
{
if (path_exists(p))
strcpy(last_path, p);
}
}
bool select_single(char *filename, char *mask, char *title)
{
PATH path = "";
FILENAME name = "";
bool ok;
if (filename[0] != EOS)
split_filename(filename, path, name);
else
strcpy(path, last_path);
ok = select_file(path, name, mask, title, FSCB_NULL);
if (ok && name[0] != EOS) /* für den Fall, daß nur ein Verzeichnis kommt */
{
strcpy(filename, path);
strcat(filename, name);
store_path(path);
}
return ok;
}
bool select_path(char *pathname, char *title)
{
PATH path = "";
FILENAME name = "";
bool ok;
if (pathname[0] != EOS)
split_filename(pathname, path, NULL);
else
strcpy(path, last_path);
ok = select_file(path, name, "", title, FSCB_NULL);
if (ok) /* für den Fall, daß nur ein Verzeichnis kommt */
{
strcpy(pathname, path);
store_path(path);
}
return ok;
}
static int open_multi(char *path, char *name)
{
if (name[0] != EOS) /* für den Fall, daß nur ein Verzeichnis kommt */
{
PATH filename;
int r;
strcpy(filename, path);
strcat(filename, name);
if (!shift_pressed() && filematch(filename, "*.QPJ", -1))
r = load_projekt(filename);
else
r = load_edit(filename, multi_bin);
if (r > 0)
send_dhst(filename);
}
return TRUE;
}
void select_multi(bool binary)
{
PATH path;
FILENAME name = "";
char *title;
multi_bin = binary;
strcpy(path, last_path);
if (binary)
title = rsc_string(LOADBINSTR);
else
title = rsc_string(LOADFILESTR);
select_file(path, name, "", title, open_multi);
}
/******************************************************************************/
void init_file(void)
{
get_path(last_path, 0); /* Aktuellen Pfad holen */
}
void term_file(void)
{
}